package com.chenqq.qsocket.tools;

import com.chenqq.qsocket.configuration.MinaConfigInfo;
import com.chenqq.qsocket.handler.FileMessageHandler;
import com.chenqq.qsocket.message.FileTask;
import com.chenqq.qsocket.message.RequestSendFileMessage;

import java.io.File;

import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;

public class FileSender {
    private SendFileListener sendFileListener;

    public void sendFile(final String filePath, SendFileListener sendFileListener) {
        this.sendFileListener=sendFileListener;
        zippedFile(filePath);
    }

    public interface SendFileListener {
        public void onSucess(RequestSendFileMessage requestSendFileMessage);

        public void onFailed(String hint);
    }

    private void zippedFile(String filePath) {
        Disposable subscribe = BehaviorSubject.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext(filePath);

            }
        }).unsubscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .map(new Function<String, Object>() {
                    @Override
                    public Object apply(@NonNull String path) throws Exception {
                        FileTask fileTask = new FileTask();
                        fileTask.fileSegmentSize = MinaConfigInfo.getInStance().getSizePartSize();
                        fileTask.filePath = path;
                        File file = new File(path);
                        if (!file.exists()) {
                            return "文件不存在" + path;
                        }
                        fileTask.md5 = new FileCheck().getFileMD5String(file);
                        fileTask.id = System.currentTimeMillis();
                        fileTask.fileName = file.getName();
                        fileTask.startTime = fileTask.id;
                        fileTask.size = file.length();
                        fileTask.isZipped= MinaConfigInfo.getInStance().isNeedZip();
                        boolean zipped = FileMessageHandler.zipFile(fileTask);
                        if (!zipped) {
                            return "文件压缩失败";
                        }
                        FileMessageHandler.getFileTasks(false).put(fileTask.id, fileTask);
                        fileTask.startTime2 = System.currentTimeMillis();
                        RequestSendFileMessage requestSendFileMessage = new RequestSendFileMessage(fileTask);
                        System.out.println("请求发送文件 " + fileTask.filePath + " id " + fileTask.id
                        +" 压缩后文件 "+fileTask.zippedFilePath);
                        return requestSendFileMessage;
                    }
                }).observeOn(Schedulers.io()).subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        if (o instanceof String){
                            if (sendFileListener!=null){
                                sendFileListener.onFailed((String) o);
                            }
                        }
                        if (o instanceof RequestSendFileMessage){
                            if (sendFileListener!=null){
                                sendFileListener.onSucess((RequestSendFileMessage) o);
                            }
                        }
                        MinaConfigInfo.getInStance().removeDisposable(filePath);

                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        if (sendFileListener!=null){
                            sendFileListener.onFailed(throwable.getLocalizedMessage());
                        }
                        MinaConfigInfo.getInStance().removeDisposable(filePath);
                    }
                });
        MinaConfigInfo.getInStance().addDisposable(filePath,subscribe);
    }


}
